# 导入库——qq邮箱测试，其他邮箱略有差异
import poplib,datetime,time,os
from sys import exec_prefix
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import time
import os
class AttDown:
    def __init__(self,save_path) -> None:
        self.email_user='1250853776@qq.com'
        self.password='egvlpjzunwvcicbd'
        self.pop3_server='pop.qq.com'
        self.save_path = save_path
        os.makedirs(self.save_path,exist_ok=True)
        self.mails,self.server = self.email_login(self.email_user,self.password,self.pop3_server)
        self.prev_counts = len(self.mails)
        self.msg = []
        self.current_filename = []
        # self.scan_email()
    
    def email_login(self,email_user,password,pop3_server):
        server=poplib.POP3_SSL(pop3_server,995,timeout=10)
        # 身份认证:
        server.user(email_user)
        server.pass_(password)
        
        # 返回邮件数量和占用空间:
        print('Messages: %s. Size: %s'%server.stat())

        resp,mails,octets = server.list()
        
        return mails,server

    def scan_email(self):
        for i in range(1,len(self.mails)+1):
            print(i)
            try:
                resp,lines,octets = self.server.retr(i)
                msg_content=b'\r\n'.join(lines).decode()
                # 解析邮件:
                msg = Parser().parsestr(msg_content)
                
                From = parseaddr(msg.get('from'))[1]#发件人
                To = parseaddr(msg.get('To'))[1]#收件人
                Cc = parseaddr(msg.get_all('Cc'))[1]#抄送人
                Subject = self.decode_str(parseaddr(msg.get('Subject'))[1])#主题
                self.msg.append(msg)

                # # 获取邮件时间,格式化收件时间
                # date1 = time.strptime(msg.get("Date")[0:24],'%a, %d %b %Y %H:%M:%S')
                # # 邮件时间格式转换
                # date2 = time.strftime("%Y-%m-%d",date1)
                # print(f'发件人：{From}；收件人：{To}；抄送人：{Cc}；主题：{Subject}；收件日期：{date2}')
                # # 主题和日期验证所需邮件
            except:
                continue
        print("Scan finish.")

    def update_email(self):
        resp,mails,octets = self.server.list()
        if self.prev_counts != len(mails):
            self.prev_counts = len(mails)
            try:
                resp,lines,octets = self.server.retr(len(mails))
                msg_content=b'\r\n'.join(lines).decode()
                # 解析邮件:
                msg = Parser().parsestr(msg_content)
                self.msg.append(msg)
                From = parseaddr(msg.get('from'))[1]#发件人
                To = parseaddr(msg.get('To'))[1]#收件人
                Cc = parseaddr(msg.get_all('Cc'))[1]#抄送人
                Subject = self.decode_str(parseaddr(msg.get('Subject'))[1])#主题
                self.save_att_file(msg,self.save_path)
                return True
            except:
                return False
        else:
            self.prev_counts = len(mails)
        return False

    def decode_str(self,str_in):
        """字符编码转换"""
        value, charset = decode_header(str_in)[0]
        if charset:
            value = value.decode(charset)
        return value

    def get_file_list(self):
        return self.current_filename
    
    def empty_file_list(self):
        self.current_filename = []

    def save_att_file(self,msg,save_path):
        """附件下载函数"""
        for part in msg.walk():
            file_name = part.get_filename()
            # contentType = part.get_content_type()
            attachment_files =[]
            if file_name:
                file_name = self.decode_str(file_name)
                self.current_filename.append(file_name)
                data =  part.get_payload(decode=True)
                att_file = open(os.path.join(save_path,file_name), 'wb')
                attachment_files.append(file_name)
                att_file.write(data)
                att_file.close()
                print(f"附件 {file_name} 下载完成")


if __name__ == "__main__":
    test = AttDown()
    start_time = time.time()
    while time.time() - start_time < 30:
        res = test.update_email()
        print(res)
        if res:
            break
        time.sleep(5)
